package com.liangdemo.web.bigData;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.liangdemo.web.mapper.BigDataTestMapper;

/**
 * @author: LiangErLe
 * @date: 2022/10/27
 **/
@Service
public class BigDataTestServiceImpl extends ServiceImpl<BigDataTestMapper, BigDataTest> implements BigDataTestService {

    /**
     * 获取cpu最大线程数
     */
    private static final int CPU_NUM = Runtime.getRuntime().availableProcessors();

    @Autowired
    private BigDataTestMapper bigDataTestMapper;


    /**
     * 将一组数据固定分组，每组n个元素
     * 
     * @param source 要分组的数据源
     * @param n 每组n个元素
     * @param <T>
     * @return
     */
    public static <T> List<List<T>> fixedGrouping(List<T> source, int n) {

        if (null == source || source.size() == 0 || n <= 0) {
            return null;
        }
        List<List<T>> result = new ArrayList<List<T>>();
        int remainder = source.size() % n;
        int size = (source.size() / n);
        for (int i = 0; i < size; i++) {
            List<T> subset = null;
            subset = source.subList(i * n, (i + 1) * n);
            result.add(subset);
        }
        if (remainder > 0) {
            List<T> subset = null;
            subset = source.subList(size * n, size * n + remainder);
            result.add(subset);
        }
        return result;
    }

    public List test() {
        List list = new LinkedList<>();
        for (int i = 1; i < 20000; i++) {
            BigDataTest bigDataTest = new BigDataTest();
            bigDataTest.setData(String.valueOf(i));
            list.add(bigDataTest);
        }
        return list;
    }

    public static final int cpuNum = Runtime.getRuntime().availableProcessors();

    @Override
    public void save1() {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(cpuNum, cpuNum*2, 500, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(), new ThreadFactoryBuilder().build(), new ThreadPoolExecutor.AbortPolicy());
        final long star = System.currentTimeMillis();
        final AtomicInteger atomicInteger = new AtomicInteger();

        System.out.println(
            "=================================================================================================");
        System.out.println("开始执行线程-----开始保存数据");
        System.out.println(
            "=================================================================================================");

        for (int i = 0; i < 50; i++) {
            threadPoolExecutor.execute(() -> {
                batchSave(test(), Thread.currentThread().getName());
            });
        }

        threadPoolExecutor.shutdown();
        try {
            threadPoolExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(
            "=================================================================================================");
        System.out.println("线程执行完成");
        System.out.println("数据保存完成");
        System.out.println("消耗时间：" + (System.currentTimeMillis() - star) / 1000 + "秒");
        System.out.println(
            "=================================================================================================");
    }

    public void batchSave(List list, String threadName) {
        saveBatch(list);
    }

}
